<!DOCTYPE html>
<html>
  
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="utf-8">
  <meta name="author" content="Amos Zhu">
  
  
  <title>策略模式+Spring——让我们的代码更加高大上一点 | Amos的技术博客</title>

  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  
    <meta name="keywords" content="stuff,springboot2,策略模式,spring,">
  

  
  <meta name="description" content="if…else if…else 代码是实际的项目代码中出现的比例还是蛮高的，特别是针对一些业务需求根据不同类型来进行不同的业务处理，针对这种业务模型，我们来试着使用策略模式结合Spring来优化我们的代码，让代码更加高大上一点">

  

  
    <script src="//cdn.jsdelivr.net/npm/leancloud-storage@3.11.1/dist/av-min.js" async></script>
  

  
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML" async></script>
  

  
    <script src="//unpkg.com/valine/dist/Valine.min.js" async></script>
  

  

  <script>
  // theme-ad's config script
  // it can be used in every script
  
  window.AD_CONFIG = {
    leancloud: {"appid":"eObxCkTJ6j4GzRxGLgiHyfJa-gzGzoHsz","appkey":"fzRMAFC6MCE11mp7mnvh4Kwe","comment":true,"count":true},
    welcome: {"enable":true,"interval":30},
    start_time: "2019-05-28",
    passwords: ["efe07af7441da2b69c4a41e42e73be4db47f66010a56900788a458354a7373ec", ],
    is_post: true,
    lock: false,
    author: "Amos Zhu",
    share: {"qq":true,"wechat":true},
    mathjax: true,
    page_type: "",
    root: "/blog/"
  };
</script>

  <script src="/blog/vendor/sha256.min.js"></script>
<script src="/blog/js/auth.js"></script>
<script src="/blog/js/index.js"></script>
<script src="/blog/vendor/qrcode.min.js"></script>

  
    <link rel="icon" href="/blog/images/favicon.ico">
    <link rel="apple-touch-icon" href="/blog/images/touch-icon.png">
  

  <link href="//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

  <link rel="stylesheet" href="/blog/css/index.css">
<link rel="stylesheet" href="/blog/styles/components/highlight/highlight.css">

  
</head>
  <body>
    <header class="site-header">
  <div class="site-header-brand">
    
      <span class="site-header-brand-title">
        <a href="/blog/">Amos Zhu</a>
      </span>
    
    
      <span class="site-header-brand-motto"> | 当浮躁的心静不下，不妨写些东西或者看会书</span>
    
  </div>
  <div class="site-header-right">
    <nav class="site-header-navigation">
      
        <a href="/blog/" target="_self">首页</a>
      
        <a href="/blog/archives/" target="_self">归档</a>
      
        <a href="/blog/tags/" target="_self">标签</a>
      
        <a href="/blog/categories/" target="_self">分类</a>
      
        <a href="/blog/redis/" target="_self">redis</a>
      
        <a href="/blog/rabbitMQ/" target="_self">rabbitMQ</a>
      
        <a href="/blog/elasticsearch" target="_self">elasticsearch</a>
      
        <a href="/blog/stuff" target="_self">stuff</a>
      
        <a href="/blog/kafka" target="_self">kafka</a>
      
        <a href="/blog/friends/" target="_self">友链</a>
      
        <a href="/blog/about/" target="_self">关于</a>
      
    </nav>
    <div class="site-header-btn">
      
        <a href="https://gitee.com/amos_zhu" target="_blank" id="site-github">
          <i class="fa fa-github-alt"></i>
        </a>
      
      <a href="javascript:void(0);" id="site-search">
        <i class="fa fa-search"></i>
      </a>
      <a href="javascript:void(0);" id="site-nav-btn">
        <i class="fa fa-ellipsis-v"></i>
      </a>
    </div>
  </div>
</header>
<nav class="table-content" id="site-nav">
  <div class="table-content-title">
    <span>导航</span>
  </div>
  <div class="table-content-main">
    <ol class="toc">
      
        <li class="toc-item">
          <a href="/blog/" target="_self">
            首页
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/archives/" target="_self">
            归档
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/tags/" target="_self">
            标签
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/categories/" target="_self">
            分类
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/redis/" target="_self">
            redis
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/rabbitMQ/" target="_self">
            rabbitMQ
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/elasticsearch" target="_self">
            elasticsearch
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/stuff" target="_self">
            stuff
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/kafka" target="_self">
            kafka
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/friends/" target="_self">
            友链
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/about/" target="_self">
            关于
          </a>
        </li>
      
    </ol>
  </div>
</nav>
<div id="site-process"></div>
    <main>
      
  <div class="passage">
  <div class="passage-meta">
    <span>
      <i class="fa fa-calendar"></i>2019-09-28
    </span>
    
      <span>
        | <a href="/blog/categories/stuff/"><i class="fa fa-bookmark"></i>stuff</a>
      </span>
    
    
      <span>
        | <i class="fa fa-unlock-alt"></i>UNLOCK
      </span>
    
  </div>
  <h1 class="passage-title">
    策略模式+Spring——让我们的代码更加高大上一点
  </h1>
  
  <article class="passage-article">
    <br>为了更好得结合业务来实现代码，先简单的介绍一下具体的业务逻辑模型：<p></p>

<blockquote>
<p>目前有一个功能，需要打印表单设置的内容，处理表单固有的属性之外，用户可以维护自定义属性，每个自定义属性可以设置不同的处理业务逻辑，打印时，根据自定义属性来处理相关的数据，并且返回数据</p>
</blockquote>
<p>上面就是简单的具体的业务模型，我们将业务具体到代码中<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 定义自定义属性处理根据不同的类型来处理的接口</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">CustomerPropertiesHandler</span> </span>&#123;</span><br><span class="line">    <span class="function">String <span class="title">handle</span><span class="params">(Object data)</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 自定义属性合计运算处理</span></span><br><span class="line"><span class="comment"> */</span>    </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ArithmeticPropertySummationHandle</span> <span class="title">implement</span> <span class="title">CustomerPropertiesHandler</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">handle</span><span class="params">(Object data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"合计运算"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 自定义属性相乘后合计运算处理</span></span><br><span class="line"><span class="comment"> */</span>  </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ArithmeticMultiPropertySummationHandle</span> <span class="title">implement</span> <span class="title">CustomerPropertiesHandler</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">handle</span><span class="params">(Object data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"相乘后合计运算"</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 自定义属性处理</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomerPropertiesHandle</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     *  打印的数据</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">private</span> Object data;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">CustomerPropertiesHandle</span><span class="params">(Object data)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.data = data;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">CustomerPropertiesHandle</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">     <span class="comment">/**</span></span><br><span class="line"><span class="comment">      * 处理</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">handle</span><span class="params">(String type)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">"1"</span>.equals(type))&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> ArithmeticPropertySummationHandle().handle(data);</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="string">"2"</span>.equals(type)) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> ArithmeticMultiPropertySummationHandle().handle(data);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>上面就是我们根据业务模型编写的伪代码，这样的代码 如果新增了新的自定义属性的运算规则，则需要修改<code>CustomerPropertiesHandle</code>这个类，上面只是简单的代码实现，如果代码逻辑复杂的话，相应的代码变动就会增加风险</p>
<p>通过业务模型分析，我们需要将处理的模型固定不变，对于自定义属性的运算的变更，应该是不影响<code>CustomerPropertiesHandle</code>的代码实现，这样的代码符合开闭原则，也是本博文需要实现的</p>
<p>上面的伪代码已经使用了策略模式，本博文的主题是使用策略模式和Spring整合在一起来实现上面的业务，所以我们现在需要继承Spring的环境，为了方便，我们使用SpringBoot来实现,对应的版本是:<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">parent</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.1.3.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">relativePath</span>/&gt;</span> <span class="comment">&lt;!-- lookup parent from repository --&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">parent</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<h3 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h3><p>从上面的代码中，我们可以看出代码需要知道类型才能去判断调用哪种处理器来处理，so：</p>
<p><strong>思路：提供一个方法通过类型来获取对应的处理器</strong></p>
<p>我们的思路有了，但是怎么来是实现呢，这里我们可以利用Spring的特性，Spring在启动之后，解析对应的bean保存到内存中，我们这里需要处理下，在Spring的Bean容器中获取自定义属性对应的处理器，并且组装起来方便获取，最好是使用单例模式来确保线程安全性</p>
<p>有了对应的思路，我们就来实现相应的代码。<br>首先定义自定义属性的处理公共接口以及抽象类<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: CustomerPropertiesHandler</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.biz</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 定义自定义属性处理的入口方法</span></span><br><span class="line"><span class="comment"> * 所有自定义属性处理器都需要实现该接口</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/26 0026 下午 14:05</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">CustomerPropertiesHandler</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取自定义属性的类型</span></span><br><span class="line"><span class="comment">     * 该还有种方法是可以自定义注解来指定自定义属性的类型</span></span><br><span class="line"><span class="comment">     * 方法是 在该接口的实现类中添加注解，注解中指定该自定义属性的类型</span></span><br><span class="line"><span class="comment">     * 接着在 CustomPropertiesTypeBeanInitialization 中通过反射获取所有含有该注解的类</span></span><br><span class="line"><span class="comment">     * 最后再组装对应的map数据（参考CustomPropertiesTypeBeanInitialization）</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 返回值直接使用自定义属性类型的枚举</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function">CustomerPropertiesTypeEnum <span class="title">type</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 自定义属性处理</span></span><br><span class="line"><span class="comment">     * 实现类来处理对应的业务逻辑</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> data 需要处理的数据</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function">String <span class="title">handler</span><span class="params">(Object data)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: AbstractCustomerPropertiesHandler</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.biz</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 通用的自定义属性运算处理</span></span><br><span class="line"><span class="comment"> * 新增这一层是为了拓展每个运算属性中通用的功能，减少代码量</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/26 0026 上午 11:48</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">AbstractCustomerPropertiesHandler</span> <span class="keyword">implements</span> <span class="title">CustomerPropertiesHandler</span> </span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">final</span> Logger logger = LoggerFactory.getLogger(<span class="keyword">this</span>.getClass());</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>然后是自定义属性类型的各种不同的处理实现(这里没有具体的处理的内容，只有简化后的结构模型)<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br></pre></td><td class="code"><pre><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ClassName</span>: CustomePropertiesArithmeticMultiSummationHandler</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.biz.impl</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Description</span>: 相乘后合计运算</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@date</span>: 2019/9/26 0026 下午 15:07</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Component</span></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomePropertiesArithmeticMultiSummationHandler</span> <span class="keyword">extends</span> <span class="title">AbstractCustomerPropertiesHandler</span> </span>&#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> CustomerPropertiesTypeEnum <span class="title">type</span><span class="params">()</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> CustomerPropertiesTypeEnum.arithmeticMultiSummation;</span><br><span class="line">        &#125;</span><br><span class="line">    </span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> String <span class="title">handler</span><span class="params">(Object data)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">this</span>.logger.info(<span class="string">"相乘后合计运算"</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="string">"相乘后合计运算"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ClassName</span>: CustomePropertiesSummationHandler</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.biz.impl</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Description</span>: 合计运算处理器</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@date</span>: 2019/9/26 0026 下午 14:52</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Component</span></span><br><span class="line">    <span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomePropertiesSummationHandler</span> <span class="keyword">extends</span> <span class="title">AbstractCustomerPropertiesHandler</span> </span>&#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> String <span class="title">handler</span><span class="params">(Object data)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">this</span>.logger.info(<span class="string">"合计运算"</span>);</span><br><span class="line">            <span class="keyword">return</span> <span class="string">"合计运算"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    </span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> CustomerPropertiesTypeEnum <span class="title">type</span><span class="params">()</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> CustomerPropertiesTypeEnum.summation;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: CustomerPropertiesTypeEnum</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.biz.type</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 自定义属性类型枚举</span></span><br><span class="line"><span class="comment"> * 如果需要新增属性时，只需要在此枚举中新增对应的属性即可</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/26 0026 下午 13:41</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> CustomerPropertiesTypeEnum implements BaseEnum &#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 合计运算</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    summation(<span class="string">"summation"</span>),</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 相乘后合计运算</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    arithmeticMultiSummation(<span class="string">"arithmeticMultiSummation"</span>);</span><br><span class="line">    String code;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getKey</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.code;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> EnumFindHelper&lt;CustomerPropertiesTypeEnum, String&gt; CODE_HELPER</span><br><span class="line">            = <span class="keyword">new</span> EnumFindHelper(CustomerPropertiesTypeEnum.class, <span class="keyword">new</span> EnumFindHelper.EnumKeyGetter&lt;CustomerPropertiesTypeEnum, String&gt;() &#123;</span><br><span class="line"></span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> String <span class="title">getKey</span><span class="params">(CustomerPropertiesTypeEnum enumValue)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> enumValue.code;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> CustomerPropertiesTypeEnum <span class="title">getByCode</span><span class="params">(String code)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> CODE_HELPER.find(code);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>上述代码中的自定义了<code>EnumFindHelper</code>来实现通过code查找枚举对象，该操作类的实现可以参考我的相关的博客TODO</p>
<p>上面的代码其实使用的就是简化版本地策略模式，只不过还没有相对应的策略处理模型，接下来我们就来封装策略处理模型代码。</p>
<p>按照上面的思路，我们需要在系统启动后，组装对应的数据接口，为什么需要等到系统启动之后呢？由于该项目是SpringBoot框架我们的自定义属性处理器都是注入到Spring的Bean容器中的，我们需要再从Bean容器中获取到，然后组装我们需要的数据接口<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: CustomPropertiesTypeBeanInitialization</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.biz.util</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 自定义属性处理器和自定义属性类型数据初始化</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 通过自定义属性处理接口来获取所有的自定义属性处理器</span></span><br><span class="line"><span class="comment"> * 组装每个自定义属性处理器对应的类型</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 以Map结构来存储</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * 这里之所以使用枚举对象是为了解决hash冲突的现象</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/26 0026 下午 16:07</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomPropertiesTypeBeanInitialization</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> Logger logger = LoggerFactory.getLogger(CustomPropertiesTypeBeanInitialization.class);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 首先获取</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Map&lt;CustomerPropertiesTypeEnum, CustomerPropertiesHandler&gt; <span class="title">getMap</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        logger.info(<span class="string">"init..."</span>);</span><br><span class="line"></span><br><span class="line">        Map&lt;CustomerPropertiesTypeEnum, CustomerPropertiesHandler&gt; map</span><br><span class="line">                = <span class="keyword">new</span> HashMap&lt;&gt;(CustomerPropertiesTypeEnum.values().length);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 首先获取 CustomerPropertiesHandler 接口的所有的实现类</span></span><br><span class="line">        Map&lt;String, CustomerPropertiesHandler&gt; clazzes = SpringContext.getApplicationContext().getBeansOfType(CustomerPropertiesHandler.class);</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span> (Map.Entry&lt;String, CustomerPropertiesHandler&gt; entry : clazzes.entrySet()) &#123;</span><br><span class="line"></span><br><span class="line">            logger.info(<span class="string">"解析到的class文件：&#123;&#125;"</span>, entry.getValue().getClass());</span><br><span class="line">            CustomerPropertiesHandler handler = SpringContext.getBean(entry.getValue().getClass());</span><br><span class="line">            map.put(handler.type(), handler);</span><br><span class="line">        &#125;</span><br><span class="line">        logger.info(<span class="string">"解析后的customPropertiesMap:&#123;&#125;"</span>, JSONObject.toJSONString(map));</span><br><span class="line">        <span class="keyword">return</span> map;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure></p>
<p>操作类有了，这里我们可以使用单例模式来获取这个Map接口，然后在系统启动的时候来调用实例化单例<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: CustomePropertiesTypeSingleton</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 自定义属性类型单例</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/26 0026 下午 15:19</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomePropertiesTypeSingleton</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">private</span> <span class="title">CustomePropertiesTypeSingleton</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">Singleton</span> </span>&#123;</span><br><span class="line">        <span class="keyword">private</span> <span class="keyword">static</span> Map&lt;CustomerPropertiesTypeEnum, CustomerPropertiesHandler&gt; map;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">static</span> &#123;</span><br><span class="line"></span><br><span class="line">            map = CustomPropertiesTypeBeanInitialization.getMap();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Map&lt;CustomerPropertiesTypeEnum, CustomerPropertiesHandler&gt; <span class="title">getInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> map;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Map&lt;CustomerPropertiesTypeEnum, CustomerPropertiesHandler&gt; <span class="title">getInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> Singleton.getInstance();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: CustomPropertiesTypeRunner</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.runner</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/26 0026 下午 16:38</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomPropertiesTypeRunner</span> <span class="keyword">implements</span> <span class="title">ApplicationRunner</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">final</span> Logger logger = LoggerFactory.getLogger(<span class="keyword">this</span>.getClass());</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">run</span><span class="params">(ApplicationArguments args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.logger.info(<span class="string">"自定义属性类型初始化"</span>);</span><br><span class="line">        Map&lt;CustomerPropertiesTypeEnum, CustomerPropertiesHandler&gt; map = CustomePropertiesTypeSingleton.getInstance();</span><br><span class="line">        CustomerPropertiesHandler handler = map.get(CustomerPropertiesTypeEnum.arithmeticMultiSummation);</span><br><span class="line">        handler.handler(<span class="keyword">null</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>这样我们就完成了在系统启动的时候完成了自定义属性处理器和自定义属性类型的Map接口，接下来我们来测试下是否满足我们的需求，编写测试方法<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: CustomPropertiesController</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.proxyandspring.web</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>: 自定义属性Controller</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/27 0027 上午 9:51</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(value = <span class="string">"/custom-properties"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomPropertiesController</span> <span class="keyword">extends</span> <span class="title">BaseController</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@GetMapping</span>(value = <span class="string">"/handle/&#123;handler&#125;"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Result <span class="title">customProperties</span><span class="params">(@PathVariable(<span class="string">"handler"</span>)</span> CustomerPropertiesTypeEnum typeEnum) </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.logger.info(typeEnum.toString());</span><br><span class="line">        <span class="keyword">return</span> ResultWapper.success(CustomePropertiesTypeSingleton.getInstance().get(typeEnum).handler(<span class="keyword">null</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>上面代码中的参数为枚举类型，SpringBoot对接收参数为枚举类型的，需要转换下类型,这里我们进行如下设置，代码不做详细说明，博友可以参考网上相关配置说明：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: EnumConverterFactory</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.common.service</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/27 0027 上午 10:35</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EnumConverterFactory</span> <span class="keyword">implements</span> <span class="title">ConverterFactory</span>&lt;<span class="title">String</span>, <span class="title">BaseEnum</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Map&lt;Class, Converter&gt; convertMap = <span class="keyword">new</span> ConcurrentHashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> &lt;T extends BaseEnum&gt; <span class="function">Converter&lt;String, T&gt; <span class="title">getConverter</span><span class="params">(Class&lt;T&gt; aClass)</span> </span>&#123;</span><br><span class="line">        Converter converter = convertMap.get(aClass);</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">null</span> == converter) &#123;</span><br><span class="line">            converter = <span class="keyword">new</span> EnumConverter(aClass);</span><br><span class="line">            convertMap.put(aClass, converter);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> converter;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">class</span> <span class="title">EnumConverter</span>&lt;<span class="title">T</span> <span class="keyword">extends</span> <span class="title">BaseEnum</span>&gt; <span class="keyword">implements</span> <span class="title">Converter</span>&lt;<span class="title">String</span>, <span class="title">T</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">private</span> Class&lt;T&gt; clazz;</span><br><span class="line">        <span class="keyword">private</span> Map&lt;String, T&gt; enumMap = <span class="keyword">new</span> ConcurrentHashMap&lt;&gt;();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        <span class="function"><span class="keyword">public</span> <span class="title">EnumConverter</span><span class="params">(Class&lt;T&gt; clazz)</span> </span>&#123;</span><br><span class="line">            <span class="keyword">this</span>.clazz = clazz;</span><br><span class="line"></span><br><span class="line">            T[] enums = clazz.getEnumConstants();</span><br><span class="line">            <span class="keyword">for</span> (T anEnum : enums) &#123;</span><br><span class="line">                <span class="keyword">this</span>.enumMap.put(anEnum.getKey(), anEnum);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="function"><span class="keyword">public</span> T <span class="title">convert</span><span class="params">(String key)</span> </span>&#123;</span><br><span class="line">            T result = <span class="keyword">this</span>.enumMap.get(key);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (<span class="keyword">null</span> == result) &#123;</span><br><span class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"params is wrong"</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> result;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Copyright © 2018 五月工作室. All rights reserved.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Project</span>: stuff</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ClassName</span>: WebAppConfigurer</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Package</span>: com.amos.stuff.common.config</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: zhuqb</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Description</span>:</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span>: 2019/9/27 0027 上午 10:49</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Version</span>: V1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">WebAppConfigurer</span> <span class="keyword">implements</span> <span class="title">WebMvcConfigurer</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addFormatters</span><span class="params">(FormatterRegistry registry)</span> </span>&#123;</span><br><span class="line">        registry.addConverterFactory(<span class="keyword">new</span> EnumConverterFactory());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>接下来我们使用postman来执行测试下，应该可以看到想要的结果了</p>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>如果需要接入我们上面的代码，需要添加一种自定义属性处理器则需要如下的操作</p>
<ul>
<li>在 <code>CustomerPropertiesTypeEnum</code>类中添加自定义属性类型</li>
<li>新增继承 <code>AbstractCustomerPropertiesHandler</code>的对应的自定义属性处理器，并且在<code>type</code>方法中返回自定义属性类型</li>
</ul>
<p>完成以上两步的接入就可以使用了</p>
<p>详细代码，可以参考我的<a href>Gitee</a></p>
  </article>
  <aside class="table-content" id="site-toc">
  <div class="table-content-title">
    <i class="fa fa-arrow-right fa-lg" id="site-toc-hide-btn"></i>
    <span>目录</span>
  </div>
  <div class="table-content-main">
    <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#思路"><span class="toc-text">思路</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#总结"><span class="toc-text">总结</span></a></li></ol>
  </div>
</aside>
  
    <aside class="passage-copyright">
      <div>本文作者: Amos Zhu</div>
      
        <div>
          原文链接: 
          <a href target="_blank">http://amos_zhu.gitee.io/passages/策略模式-Spring——让我们的代码更加高大上一点/</a>
        </div>
      
      <div>
        版权声明: 本博客所有文章除特别声明外, 均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> 许可协议. 转载请注明出处!
      </div>
    </aside>
  
  
    <div class="passage-tags">
     
      <a href="/blog/tags/springboot2/"><i class="fa fa-tags"></i>springboot2</a>
     
      <a href="/blog/tags/策略模式/"><i class="fa fa-tags"></i>策略模式</a>
     
      <a href="/blog/tags/spring/"><i class="fa fa-tags"></i>spring</a>
    
    </div>
  
</div>

    </main>
    
      
<div class="site-comment-contanier" data-plateform="leancloud">
  
    <p id="site-comment-info">
      <i class="fa fa-spinner fa-spin"></i> 评论加载中
    </p>
    <div id="site-comment"></div>
  
</div>
    
    <div class="site-footer-wrapper">
  <footer class="site-footer">
    
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">博客推荐</h5>
          
            <span class="site-footer-item">
              <a href="http://youzhixueyuan.com/series/java" target="_blank">优知学院</a>
            </span>
          
            <span class="site-footer-item">
              <a href="http://ruanyifeng.com/" target="_blank">阮一峰的个人网站</a>
            </span>
          
        </div>
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">系列教程</h5>
          
            <span class="site-footer-item">
              <a href="http://amos_zhu.gitee.io/blog/redis" target="_blank">Redis系列教程</a>
            </span>
          
            <span class="site-footer-item">
              <a href="http://amos_zhu.gitee.io/blog/rabbitMQ/" target="_blank">RabbitMQ教程</a>
            </span>
          
            <span class="site-footer-item">
              <a href="http://amos_zhu.gitee.io/blog/kafka/" target="_blank">Kafka架构探险</a>
            </span>
          
        </div>
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">抓到我</h5>
          
            <span class="site-footer-item">
              <a href="https://gitee.com/amos_zhu" target="_blank">Gitee</a>
            </span>
          
            <span class="site-footer-item">
              <a href="https://blog.csdn.net/wdcl2468" target="_blank">CSDN</a>
            </span>
          
            <span class="site-footer-item">
              <a href="https://www.jianshu.com/u/2dbe61b1f3c3" target="_blank">简书</a>
            </span>
          
        </div>
      
    
    <div class="site-footer-info">
      <i class="fa fa-clock-o"></i> 本站已稳定运行<span id="site-time"></span>
    </div>
    
      <div class="site-footer-info">
        <i class="fa fa-paw"></i> 您是本站第 <span id="site-count"></span> 位访客
      </div>
    
    
      <div class="site-footer-info">
        <i class="fa fa-at"></i> Email: amoszhu@aliyun.com
      </div>
    
    <div class="site-footer-info">
      <i class="fa fa-copyright"></i> 
      2019 <a href="https://github.com/dongyuanxin/theme-ad/" target="_blank">Theme-AD</a>.
      Created by <a href="https://godbmw.com/" target="_blank">GodBMW</a>.
      All rights reserved.
    </div>
  </footer>
</div>
    <div id="site-layer" style="display:none;">
  <div class="site-layer-content">
    <div class="site-layer-header">
      <span class="site-layer-header-title" id="site-layer-title"></span>
      <i class="fa fa-close" id="site-layer-close"></i>
    </div>
    <div class="site-layer-body" id="site-layer-container">
      <div class="site-layer-input" id="site-layer-search" style="display: none;">
        <div class="site-layer-input-choose">
          <a href="javascript:void(0);" title="Change Search Engine">Google</a>
        </div>
        <input type="text">
        <i class="fa fa-search"></i>
      </div>
      
        <div class="site-layer-reward" id="site-layer-reward" style="display: none;">
          
            <div>
              <img src="/blog/images/wechat.png" alt="WeChat">
              
                <p>WeChat</p>
              
            </div>
          
            <div>
              <img src="/blog/images/alipay.png" alt="AliPay">
              
                <p>AliPay</p>
              
            </div>
          
        </div>
      
      <div id="site-layer-welcome" style="display:none;"></div>
    </div>
  </div>
</div>
    

<div class="bottom-bar">
  <div class="bottom-bar-left">
    <a href="/blog/passages/类以及属性集按照规则过滤——一个简单的构建思路来解决/" data-enable="true">
      <i class="fa fa-arrow-left"></i>
    </a>
    <a href="/blog/passages/一次SQL优化体验/" data-enable="true">
      <i class="fa fa-arrow-right"></i>
    </a>
  </div>
  <div class="bottom-bar-right">
    <a href="javascript:void(0);" data-enable="true" id="site-toc-show-btn">
      <i class="fa fa-bars"></i>
    </a>
    
      <a href="#site-comment" data-enable="true">
        <i class="fa fa-commenting"></i>
      </a>
    
    <a href="javascript:void(0);" id="site-toggle-share-btn">
      <i class="fa fa-share-alt"></i>
    </a>
    
      <a href="javascript:void(0);" id="site-reward">
        <i class="fa fa-thumbs-up"></i>
      </a>
    
    <a href="javascript:void(0);" id="back-top-btn">
      <i class="fa fa-chevron-up"></i>
    </a>
  </div>
</div>
    <div id="share-btn">
  
  
  
  
    <a id="share-btn-qq" href="javascript:void(0);" target="_blank">
      <i class="fa fa-qq"></i>
    </a>
  
  
    <a id="share-btn-wechat" href="javascript:void(0);" target="_blank">
      <i class="fa fa-wechat"></i>
    </a>
  
</div>
    


  <script async>
  (function(){
      var bp = document.createElement('script');
      var curProtocol = window.location.protocol.split(':')[0];
      if (curProtocol === 'https') {
          bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
      }
      else {
          bp.src = 'http://push.zhanzhang.baidu.com/push.js';
      }
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(bp, s);
  })();
  </script>



  <script async>
    (function(){
    var src = (document.location.protocol == "http:") ? "http://js.passport.qihucdn.com/11.0.1.js?":"https://jspassport.ssl.qhimg.com/11.0.1.js?";
    document.write('<script src="' + src + '" id="sozz"><\/script>');
    })();
  </script>


    
  </body>
</html>